# -*-coding:utf-8 -*-
"""
BaseModel基表
    is_delete、create_time
下面四表继承基表，可以继承两个字段
# 基表只是提供公有字段，不生成表

Book表：name、price、img、authors、publish、is_delete、create_time
Publish表：name、address、is_delete、create_time
Author表：name、age、is_delete、create_time
AuthorDetail表：mobile, author、is_delete、create_time
"""

from django.db import models
from base.models import BaseModel


class Book(BaseModel):
    name = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    img = models.ImageField(upload_to='img', default='default.jpg')

    # 410 OneToMany或ManyToOne 外键关联表，
    # 必须有on_delete
    publish = models.ForeignKey(to='Publish',  # 关联publish表
                                on_delete=models.DO_NOTHING,  # 删除出版社，该字段依旧存在,设置连表操作关系，默认为models.CASCADE 级联删除
                                db_constraint=False,
                                related_name='books',  # 反向查询字段：publish_obj.books就能查出当前出版社出版的的所有书籍
                                )
    # 420 manyToMany  多对多
    # A B  A-B表
    # def author_book(self):
    #     author_id =
    #     book_id =
    #     id =
    authors = models.ManyToManyField(to='Author',
                                     db_constraint=True,  # 断开关联
                                     related_name='books'  # 反向查询字段
                                     )

    # 方式3： 官网推荐：自定义方法属性
    def fn(self):
        return "fnfnfn"

    @property  # 属性
    def publish_name(self):
        # 自定义字段：可以连表，可以完成数据相关的逻辑
        # return "可插拔字段的值"  在fields = ()
        return self.publish.name

    @property
    def author_list(self):

        obj = self.authors.values('name', 'age', 'detail__mobile').all()
        print(obj)
        return obj

    class Meta:
        db_table = "drf_foreignkey_book"
        verbose_name = "书籍"  # 在admin中显示的文字
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


# 出版社表
class Publish(BaseModel):
    name = models.CharField(max_length=64)
    addres = models.CharField(max_length=64)

    class Meta:
        db_table = 'drf_foreignkey_publish'
        verbose_name = '出版社'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


# 作者表
class Author(BaseModel):
    name = models.CharField(max_length=64)
    age = models.IntegerField()

    class Meta:
        db_table = 'drf_foreignkey_author'
        verbose_name = '作者'  # model在admin后台显示的单数名称
        verbose_name_plural = verbose_name  # 定义的是复数名称

    def __str__(self):
        return self.name


# 作者详情
class AuthorDetail(BaseModel):
    mobile = models.CharField(max_length=11)

    # 430 OneToOne 实质是继承的ForeignKey，
    # 需要on_delete
    author = models.OneToOneField(to='Author',  # 关联的表

                                  # 310 断关联
                                  db_constraint=False,
                                  # 断关联， 默认为True
                                  # 每个表相当于独立的了，没有外键关联
                                  # 数据库不知道他两有关系，逻辑知道
                                  # 缺点：会产生脏数据，（需要逻辑判断，否则orm会判断error）

                                  # 320 反向查询字段 !!!
                                  # Authordetail.author.name   # 正向查询, 用到author关联字段
                                  # author.detail.mobile   # 反向查询，用到反向查询字段 detail
                                  related_name='detail',

                                  # 330 连表操作关系
                                  # 1）作者删除，详情删除  -  级联删除
                                  on_delete=models.CASCADE,  # 删除作者，就要删除作者详情

                                  # 2) 作者删除，详情置空
                                  # null=True
                                  # on_delete=models.SET_NULL   #外键字段清空

                                  # 3）作者删除，详情设为默认
                                  # default=0
                                  # on_delete=models.SET_DEFAULT

                                  # 4）作者删除，详情不动
                                  # on_delete=models.DO_NOTHING
                                  )

    class Meta:
        db_table = 'drf_foreignkey_author_detail'
        verbose_name = '作者详情'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.author.name
